home *** CD-ROM | disk | FTP | other *** search
- /* Window event functions.
-
- 94/01/14 aih
- - removed unneeded focus flag from WinRegister
- - added focus field to window's extra data handle
-
- 94/01/12 aih
- - added functions for getting and setting event tables
-
- 93/12/16 aih
- - split out of EventUtilLib.c
-
- 93/10/16 aih
- - WinRegister/WinUnregister and WinTabRegister/WinTabUnregister have
- no effect if we're not dealing with a window for which WinExtra would
- return true. this allows using some of the library code (e.g., ListLib)
- with windows not created by the libraries, such as customized directory
- dialog boxes.
- */
-
- #include "ArrayListLib.h"
- #include "EventPrivateLib.h"
- #include "MathLib.h"
- #include "MemoryLib.h"
- #include "RectangleLib.h"
- #include "WindowLib.h"
-
- /*----------------------------------------------------------------------------*/
- /* getting and setting the window's focus */
- /*----------------------------------------------------------------------------*/
-
- /* return the object in the window with the focus */
- EventType *WinFocus(WindowPtr window)
- {
- return(window ? WinExtraPtr(window)->focus : NULL);
- }
-
- /* set the window's focus object */
- void WinFocusSet(WindowPtr window, EventObjectType object)
- {
- if (object != WinFocus(window)->object) {
- EventType *focus = EventFindObject(WinObjects(window), object);
- WinExtraPtr(window)->focus = focus;
- }
- ensure(object ? object == WinFocus(window)->object : ! WinFocus(window));
- }
-
- /*----------------------------------------------------------------------------*/
- /* registering objects */
- /*----------------------------------------------------------------------------*/
-
- /* return the first object in the window's object list */
- EventType *WinObjects(WindowPtr window)
- {
- return(window ? WinExtraPtr(window)->objects : NULL);
- }
-
- /* Register the object as belonging to the window. The object is inserted
- at the head of the window's event list. */
- void WinRegister(WindowPtr window, EventObjectType object,
- const EventTableType *table)
- {
- if (WinHasExtra(window)) {
- EventType *objects = EventInsert(WinExtraPtr(window)->objects, object, table);
- WinExtraPtr(window)->objects = objects;
- }
- }
-
- /* remove the object from the window's event list */
- void WinUnregister(WindowPtr window, EventObjectType object)
- {
- EventType *objects;
-
- if (window && WinHasExtra(window)) {
- if (object == WinFocus(window))
- WinFocusSet(window, NULL);
- objects = EventDelete(WinExtraPtr(window)->objects, object);
- WinExtraPtr(window)->objects = objects;
- }
- }
-
- /* assign the id to the object */
- void WinRegisterID(WindowPtr window, EventObjectType object, EventIDType id)
- {
- EventType *list = EventFindObject(WinExtraPtr(window)->objects, object);
- if (list) list->id = id;
- }
-
- /* return the object with the specified ID */
- EventObjectType WinRegisteredID(WindowPtr window, EventIDType id)
- {
- EventType *item = EventFindID(WinExtraPtr(window)->objects, id);
- return(item ? item->object : NULL);
- }
-
- /*----------------------------------------------------------------------------*/
- /* getting and setting an object's event table */
- /*----------------------------------------------------------------------------*/
-
- /* return the object's event table */
- const EventTableType *WinObjectTable(WindowPtr window, EventObjectType object)
- {
- EventType *list;
-
- list = EventFindObject(WinExtraPtr(window)->objects, object);
- return(list ? list->table : NULL);
- }
-
- /* set the object's event table */
- void WinObjectTableSet(WindowPtr window, EventObjectType object,
- const EventTableType *table)
- {
- EventType *list;
-
- list = EventFindObject(WinExtraPtr(window)->objects, object);
- if (list)
- list->table = table;
- }
-
- /*----------------------------------------------------------------------------*/
- /* window tab list */
- /*----------------------------------------------------------------------------*/
-
- /* window's tab-able object list is a handle to an array of event objects */
- typedef EventType *TabListType;
- typedef TabListType *TabListPtr, **TabListHandle;
-
- /* get the window's tab key object list */
- static ArrayListHandle WinTabList(WindowPtr window)
- {
- return(WinExtraPtr(window)->tablist);
- }
-
- /* set the window's tab list */
- static void WinTabListSet(WindowPtr window, ArrayListHandle tablist)
- {
- ArrayListEnd(WinExtraPtr(window)->tablist);
- WinExtraPtr(window)->tablist = tablist;
- }
-
- /* return number of items in window's tab list */
- static short WinTabListCount(WindowPtr window)
- {
- return(WinTabList(window) ? ArrayListCount(WinTabList(window)) : 0);
- }
-
- /* true if window has a tab list with more than one object, and
- so those objects (like lists) should draw bold outlines and
- hitting the tab key should switch between objects */
- Boolean WinHasTabList(WindowPtr window)
- {
- return(WinTabListCount(window) > 1);
- }
-
- /* append the object to the window's tab list */
- void WinTabRegister(WindowPtr window, EventObjectType object)
- {
- ArrayListHandle list;
- EventType *event;
-
- if (WinHasExtra(window)) {
- event = EventFindObject(WinObjects(window), object);
- check(event != NULL);
- if (! WinTabList(window))
- WinTabListSet(window, ArrayListBegin(sizeof(TabListType)));
- list = WinTabList(window);
- ArrayListInsert(list, ArrayListCount(list));
- ArrayListSet(list, ArrayListCount(list) - 1, &event);
- }
- }
-
- /* remove the object from the window's tab list */
- void WinTabUnregister(WindowPtr window, EventObjectType object)
- {
- TabListHandle array;
- short i, nitems;
-
- if (window && WinHasExtra(window)) {
- nitems = WinTabListCount(window);
- array = ArrayListGetHandle(WinTabList(window));
- for (i = 0; i < nitems && (*array)[i]->object != object; i++)
- ;
- if (i < nitems) {
- check(EventFindObject(WinObjects(window), object) != NULL);
- ArrayListDelete(WinTabList(window), i);
- }
- }
- }
-
- /* switch to next object in window's tab list */
- void WinTab(WindowPtr window)
- {
- TabListHandle array;
- EventType *focus;
- short i, nitems;
-
- /* find object with current focus in window's tab list */
- require(WinHasTabList(window));
- focus = WinFocus(window);
- nitems = WinTabListCount(window);
- array = ArrayListGetHandle(WinTabList(window));
- for (i = 0; i < nitems && (*array)[i] != focus; i++)
- ;
- if (i < nitems) {
- /* select next object */
- focus = (*array)[(i + 1) % nitems];
- if (focus->table->focusWindow.selectall)
- focus->table->focusWindow.selectall(focus->object);
- FocusSet(focus->object);
- }
- }
-
- /*----------------------------------------------------------------------------*/
- /* resizing windows */
- /*----------------------------------------------------------------------------*/
-
- /* Get the minimum and maximum size of the window by polling every
- object in the window and merging the minimum and maximum sizes
- returned by the objects. */
- void WinSizeRect(WindowPtr window, Rect *minmax)
- {
- EventType *list;
-
- minmax->top = minmax->left = 20;
- minmax->bottom = minmax->right = SHRT_MAX;
- for (list = WinObjects(window); list; list = EventNext(list)) {
- if (list->table->window.grow) {
- Rect size = *minmax;
- list->table->window.grow(list->object, &size);
- minmax->top = max(minmax->top, size.top);
- minmax->left = max(minmax->left, size.left);
- minmax->bottom = min(minmax->bottom, size.bottom);
- minmax->right = min(minmax->right, size.right);
- }
- }
- }
-
- /* get the window's preferred width and height */
- void WinSizePreferred(WindowPtr window, short *width, short *height)
- {
- Rect portRect;
- EventType *list;
-
- WinPortRect(window, &portRect);
- *width = *height = 20;
- for (list = WinObjects(window); list; list = EventNext(list)) {
- if (list->table->window.zoom) {
- short w = RectWidth(&portRect);
- short h = RectHeight(&portRect);
- list->table->window.zoom(list->object, &w, &h);
- *width = max(*width, w);
- *height = max(*height, h);
- }
- }
- }
-
- /* resize the objects in the window */
- void WinResize(WindowPtr window, short dh, short dv)
- {
- EventType *list;
-
- if (dh != 0 || dv != 0) {
- for (list = WinObjects(window); list; list = EventNext(list)) {
- if (list->table->window.resize)
- list->table->window.resize(list->object, dh, dv);
- }
- }
- }
-